HDU-1874 畅通工程续(Dijkstra or Floyd or SPFA 模板题)

描述

传送门:HDU-1874 畅通工程续

某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。

现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。

输入描述

本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。

输出描述

对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.

示例

输入

1
2
3
4
5
6
7
8
3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2

输出

1
2
2
-1

题解

题目大意

中文题面

思路

最短路模板题,几种最短路的算法都能直接过。

代码

Dijkstra
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <bits/stdc++.h>
const int MAXN = 205, INF = 0x3f3f3f3f;
using namespace std;
int n, m;
vector<pair<int, int> >E[MAXN];
int d[MAXN], inq[MAXN];

int main(){
while(cin >> n >> m){
memset(d, INF, sizeof(d));
memset(inq, 0, sizeof(inq));
for(int i = 0; i < MAXN; i++)
E[i].clear();
for(int i = 0; i < m; i++){
int x, y, z;
cin >> x >> y >> z;
E[x].push_back(make_pair(y, z));
E[y].push_back(make_pair(x, z));
}
int s, t;
cin >> s >> t;
queue<int> que;
que.push(s);
d[s] = 0;
inq[s] = 1;
while(!que.empty()){
int now = que.front();
que.pop();
inq[now] = 0;
for(int i = 0; i < E[now].size(); i++){
int v = E[now][i].first;
if(d[v] > d[now] + E[now][i].second){
d[v] = d[now] + E[now][i].second;
if(inq[v]) continue;
inq[v] = 0;
que.push(v);
}
}
}
if(d[t] == INF) d[t] = -1;
cout << d[t] << endl;
}
}
Floyd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <bits/stdc++.h>
const int MAXN = 205, INF = 0x3f3f3f3f;
using namespace std;
int n, m;
int mp[MAXN][MAXN];
int main(){
while(cin >> n >> m){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(i == j) mp[i][j] = 0;
else mp[i][j] = INF;
}
}
for(int i = 0; i < m; i++){
int x, y, z;
cin >> x >> y >> z;
mp[x][y] = min(z, mp[x][y]);
mp[y][x] = min(z, mp[y][x]);
}
int s, t;
cin >> s >>t;
for(int k = 0; k < n; k++)
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
mp[i][j] = min(mp[i][k]+mp[k][j], mp[i][j]);

if(mp[s][t] == INF) cout << "-1" <<endl;
else cout << mp[s][t] << endl;
}
}
SPFA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <bits/stdc++.h>
const int MAXN = 205, INF = 0x3f3f3f3f;
using namespace std;
int n, m, s, t;
int inq[MAXN], dis[MAXN];
vector<pair<int, int> >E[MAXN];

int main(){
while(~scanf("%d %d", &n, &m)){
memset(dis, INF, sizeof(dis));
memset(inq, 0, sizeof(inq));
for(int i = 0; i < MAXN; i++) E[i].clear();
for(int i = 0; i < m; i++){
int x, y, z;
scanf("%d %d %d", &x, &y, &z);
E[x].push_back(make_pair(y, z));
E[y].push_back(make_pair(x, z));
}
scanf("%d %d", &s, &t);
queue<int> que;
dis[s] = 0;
que.push(s);
inq[s] = 1;
while(!que.empty()){
int now = que.front();
que.pop();inq[now] = 0;
for(int i = 0; i < E[now].size(); i++){
int v = E[now][i].first;
if(dis[v] > dis[now] + E[now][i].second){
dis[v] = dis[now] + E[now][i].second;
if(inq[v]) continue;
inq[v] = 1;
que.push(v);
}
}
}
if(dis[t] == INF) printf("-1\n");
else printf("%d\n", dis[t]);
}
}